package com.luban.authserver.config.customfilter.login;

import com.luban.authserver.bean.UserInfo;
import com.luban.authserver.config.customfilter.util.LoginUtil;
import com.luban.authserver.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import java.util.Collection;

@Component
/**
 * 主要是做用户名和密码验证
 *
 * 可以仿照 oauth 默认的 DaoAuthenticationProvider 逻辑实现，DaoAuthenticationProvider这个有个抽象父类
 * 这里就简单处理了
 */
public class CustomAuthenticationProvider implements AuthenticationProvider {
    /**
     * 注入我们自己定义的用户信息获取对象
     */
    @Autowired
    private UserServiceImpl userDetailService;

    private UserDetailsChecker userDetailsChecker = new MyPreAuthenticationCheck();

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 这个获取表单输入中返回的用户名;
        String userName = authentication.getName();
        // 这个是表单中输入的密码；
        String password = (String)authentication.getCredentials();
        // 拿到额外信息
        //MyWebAuthenticationDetails details = (MyWebAuthenticationDetails)authentication.getDetails();

        // 这里构建来判断用户是否存在和密码是否正确
        UserDetails userInfo = userDetailService.loadUserByUsername(userName); // 这里调用我们的自己写的获取用户的方法；

        userDetailsChecker.check(userInfo);


        /**
         * 登录认证
         */
        try {
            if(!userName.equals("user1") || !password.equals("123456")){
                throw new BadCredentialsException("用户名密码错误");
            }
            LoginUtil.login(userName, password);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BadCredentialsException(e.getMessage());
        }


        Collection<? extends GrantedAuthority> authorities = userInfo.getAuthorities();
        // 构建返回的用户登录成功的token
        return new CustomAuthenticationToken(userInfo, password, authorities);

    }

    @Override
    public boolean supports(Class<?> authentication) {
        /**
         * providerManager会遍历所有
         * securityconfig中注册的provider集合
         * 根据此方法返回true或false来决定由哪个provider
         * 去校验请求过来的authentication
         */
        return (CustomAuthenticationToken.class
                .isAssignableFrom(authentication));
    }
}
